package com.sunlands.deskmate.controller;

import com.alibaba.fastjson.JSON;
import com.sunlands.deskmate.client.DeskMateGroupService;
import com.sunlands.deskmate.client.UserCenterService;
import com.sunlands.deskmate.constant.NameConstant;
import com.sunlands.deskmate.dto.OnLinePeopleRequestDTO;
import com.sunlands.deskmate.dto.RequestDTO;
import com.sunlands.deskmate.message.entity.Messages;
import com.sunlands.deskmate.entity.TzChatRecord;
import com.sunlands.deskmate.message.enums.MessageType;
import com.sunlands.deskmate.channel.WebSocketServerHandler;
import com.sunlands.deskmate.message.handler.receiver.MessageReceiverFactory;
import com.sunlands.deskmate.service.MessageService;
import com.sunlands.deskmate.sstwds.ContentSecCheck;
import com.sunlands.deskmate.vo.*;
import com.sunlands.deskmate.vo.response.BusinessResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by yanliu on 2019/4/18.
 */

@RestController
@Api(tags = "聊天内容接口")
@Slf4j
@RequestMapping("/chat")
public class ChatController {

    @Autowired
    private MessageService messageService;

    @Autowired
    private WebSocketServerHandler webSocketServerHandler;

    @Autowired
    private ContentSecCheck contentSecCheck;

    @Autowired
    public RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private DeskMateGroupService deskMateGroupService;

    @Autowired
    private UserCenterService userCenterService;

    @Autowired
    private MessageReceiverFactory messageReceiverFactory;

    @ApiOperation(value = "查询未读聊天信息接口(APP端用)")
    @GetMapping("/unread")
    @PreAuthorize("isAuthenticated()")
    public BusinessResult<List<TzChatRecordVO>> unreadMessage(RequestDTO requestDTO) {
        log.info("unreadMessage request start param={}", requestDTO);
        if (requestDTO.getType() == null || requestDTO.getDestId() == null || requestDTO.getUserId() == null) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_NULL);
        }
        if (StringUtils.isBlank(requestDTO.getMaxReadId())) {
            requestDTO.setMaxReadId("0");
        }

        List<TzChatRecordVO> tzChatRecords = messageService.findUnreadRecord(requestDTO);
        log.info("unreadMessage request end result={}", tzChatRecords);
        return BusinessResult.createSuccessInstance(tzChatRecords);
    }


    @ApiOperation(value = "查询在线人员id接口(APP端用)")
    @GetMapping("/userIdsOnline")
    @PreAuthorize("isAuthenticated()")
    public BusinessResult<Set<Long>> peopleNum(OnLinePeopleRequestDTO requestDTO) {
        log.info("peopleNum request start param={}", requestDTO);
        if (StringUtils.isBlank(requestDTO.getDestId())) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_NULL);
        }
        Set<Long> list = webSocketServerHandler.getOnlineUserIdByRoomId(Long.valueOf(requestDTO.getDestId()), Integer.valueOf(MessageType.ROOM_CHAT.getType()));
        log.info("peopleNum request end result={}", list);
        return BusinessResult.createSuccessInstance(list);
    }

    @ApiOperation(value = "通过长连接发送内容接口(服务端用)")
    @PostMapping("/send")
//    @PreAuthorize("isAuthenticated()")
    public BusinessResult send(@RequestBody Messages msgEntity) {
        log.info("send request start param={}", msgEntity);
        if (msgEntity.getToId() == null) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_NULL);
        }
        if (StringUtils.isBlank(msgEntity.getFromUserId())) {
            msgEntity.setFromUserId("0");
        }
        if (StringUtils.isNotBlank(msgEntity.getMessage())) {
            msgEntity.setMessage(contentSecCheck.filterSensitiveWords(msgEntity.getMessage()));
        }
        if (msgEntity.getType().startsWith("3") && redisTemplate.hasKey(NameConstant.CLOSED_ROOM_ID_PREFIX + msgEntity.getToId())) {
            return BusinessResult.createInstance(CommonResultMessage.ROOM_CLOSED);
        }
        messageReceiverFactory.getReceiver(msgEntity.getType()).receive(null, msgEntity);
        log.info("send request end");
        return BusinessResult.createSuccessInstance(null);
    }

    @ApiOperation(value = "消息变动通知接口(服务端用)")
    @PostMapping("/inform")
    public BusinessResult inform(@RequestBody MsgChangeInformEntity msgChangeInformEntity) {
        log.info("inform request start param={}", msgChangeInformEntity);
        if (msgChangeInformEntity.getUserIds() == null) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_NULL);
        }

        List<String> userIds = msgChangeInformEntity.getUserIds();
        for (String userId : userIds) {
            try {
                Messages msgEntity = new Messages();
                msgEntity.setType(msgChangeInformEntity.getType());
                msgEntity.setToId(userId);
                messageReceiverFactory.getReceiver(msgEntity.getType()).receive(null, msgEntity);
            } catch (Exception e) {
                log.error("send inform msg error, userId={}", userId, e);
            }
        }
        return BusinessResult.createSuccessInstance(null);
    }

//    @ApiOperation(value = "调试用")
//    @GetMapping("/getCtx")
//    public BusinessResult getCtx(Long userId, String connectType) {
//        ChannelHandlerContext ctx = webSocketServerHandler.getCtx(userId, connectType);
//        return BusinessResult.createSuccessInstance("the result=" + ctx);
//    }

    @ApiOperation(value = "获取用户socket实时状态")
    @GetMapping("/getOnline")
    public BusinessResult<List<UserOnlineVO>> getOnline(@ApiParam("用户id") @RequestParam(value = "userId", required = false) Long userId) {
        return BusinessResult.createSuccessInstance(webSocketServerHandler.getOnline(userId));
    }

    @ApiOperation(value = "获取用户聊天信息")
    @GetMapping("/getBusinessOnline")
    public BusinessResult<Map> getBusinessOnline(@ApiParam("用户id") @RequestParam(value = "userId", required = false) Long userId) {
        return BusinessResult.createSuccessInstance(webSocketServerHandler.getBusinessOnline(userId));
    }

    @ApiOperation(value = "查询最近聊天信息列表(APP端用)")
    @GetMapping("/recentChatList")
//    @PreAuthorize("isAuthenticated()")
    public BusinessResult<List<RecentChatVO>> recentChatList(@RequestParam("userId") String userId) {
        log.info("recentChatList request start param={}", userId);
        List<RecentChatVO> recentChatVOList = new ArrayList<>();
        try {
            List<TzChatRecord> tzChatRecords = messageService.selectRecentChatRecord(userId);

            tzChatRecords = tzChatRecords.stream().sorted(Comparator.comparing(TzChatRecord::getType).thenComparing((t1, t2) -> -t1.getCreateTime().compareTo(t2.getCreateTime()))).collect(Collectors.toList());

            log.debug("recentChatList request start result ={}", JSON.toJSONString(tzChatRecords));
            if (tzChatRecords != null && tzChatRecords.size() > 0) {
                Map<String, Object> listInfoMap = new HashMap<>();
                for (TzChatRecord tzChatRecord : tzChatRecords) {
                    String toId = tzChatRecord.getToId();

                    if (StringUtils.isEmpty(toId)) {
                        continue;
                    }

                    if (listInfoMap.containsKey(toId)) {
                        continue;
                    }

                    RecentChatVO recentChatVO = new RecentChatVO();
                    recentChatVO.setUserId(userId);
                    recentChatVO.setDestId(toId);
                    Integer type = Integer.valueOf(tzChatRecord.getType());
                    //私聊

                    if (type != null && type.intValue() >= 100 && type.intValue() <= 199) {
                        BusinessResult<UsersVO> userInfoById = userCenterService.getUserInfoById(Long.valueOf(toId));
                        listInfoMap.put(toId, userInfoById);
                        if (0 == userInfoById.getCode().intValue() && null != userInfoById.getData()) {
                            recentChatVO.setDestAvatarUrl(userInfoById.getData().getAvatarUrl());
                            recentChatVO.setDestName(userInfoById.getData().getName());
                            recentChatVO.setType(1);
                        }
                    }
                    if (type != null && type.intValue() >= 200 && type.intValue() <= 299) {
                        BusinessResult<GroupSimpleInfo> groupSimpleInfo = deskMateGroupService.getGroupSimpleInfo(toId);
                        listInfoMap.put(toId, groupSimpleInfo);
                        if (0 == groupSimpleInfo.getCode().intValue() && null != groupSimpleInfo.getData()) {
                            recentChatVO.setDestAvatarUrl(groupSimpleInfo.getData().getAvatarFile());
                            recentChatVO.setDestName(groupSimpleInfo.getData().getGroupName());
                            recentChatVO.setType(2);
                        }

                    }
                    recentChatVOList.add(recentChatVO);
                }
            }
        } catch (Exception ex) {
            log.error("recentChatList request error, param={} ,ex={}", userId, ex);
        }
        return BusinessResult.createSuccessInstance(recentChatVOList);
    }

}
